package authx

import (
	"errors"
	"github.com/golang-jwt/jwt/v5"
	"time"
)

type CustomClaims[T any] struct {
	*jwt.RegisteredClaims
	Data T `json:"data"`
}

func CreatJwtTokenWithClaims[T any](key []byte, duration time.Duration, uc CustomClaims[T]) (string, error) {
	nowTime := time.Now()
	uc.RegisteredClaims = &jwt.RegisteredClaims{
		ExpiresAt: jwt.NewNumericDate(time.Now().Add(duration)),
		Issuer:    "constant.JWTIssuer",            // 签发人
		IssuedAt:  &jwt.NumericDate{Time: nowTime}, //签发时间
	}
	claims := jwt.NewWithClaims(jwt.SigningMethodHS256, uc)
	// 使用指定的secret签名,获取字符串token
	tokenStr, err := claims.SignedString(key)
	if err != nil {
		return "", err
	}
	return tokenStr, nil
}
func ParseWithClaims[T any](key []byte, tokenString string) (*CustomClaims[T], error) {
	// 如果令牌无效（如果令牌已根据我们设置的登录到期时间过期）或者签名不匹配,此方法会返回错误.
	if token, err := jwt.ParseWithClaims(tokenString, &CustomClaims[T]{}, func(token *jwt.Token) (any, error) {
		return key, nil
	}); err != nil {
		return nil, err
	} else {
		if claims, ok := token.Claims.(*CustomClaims[T]); ok && token.Valid {
			return claims, nil
		}
	}
	return nil, errors.New("claims err")
}
